package vip.yyzhu.redisadmin.api.key.controller;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import vip.yyzhu.redisadmin.aop.verifyKeyType.VerifyKeyType;
import vip.yyzhu.redisadmin.jopo.ResData;
import vip.yyzhu.redisadmin.jopo.ResJson;
import vip.yyzhu.redisadmin.redis.RedisList;
import vip.yyzhu.redisadmin.util.Tool;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(value = "/api/key/list", produces = "application/json;charset=UTF-8")
@SuppressWarnings("all")
public class ListController {
    @Autowired
    RedisList redisList;
    @Autowired
    Tool tool;

    ObjectMapper mapper = new ObjectMapper();

    /**
     * 往左边添加value
     *
     * @param key    list的key
     * @param values 要添加的数组，json格式
     * @return {map:{"key":key,"values":values}}
     */
    @VerifyKeyType(value = "list", empty = true)
    @RequestMapping(value = "/lpush", method = RequestMethod.POST)
    public Object lpush(HttpServletRequest request,
                        @RequestParam String key,
                        @RequestParam String values) throws Exception {
        val jedis = tool.getJedis(request);
        //json转list
        String[] list = mapper.readValue(values, String[].class);
        Long lpush = jedis.lpush(key, list);
        Map map = new HashMap();
        map.put("key", key);
        map.put("values", list);
        ResData res = new ResData(map);
        res.setRedis(lpush);
        return new ResJson(200, "成功", res);
    }

    /**
     * 往右边添加value
     *
     * @param key    list的key
     * @param values 要添加的数组，json格式
     * @return {map:{"key":key,"values":values}}
     */
    @VerifyKeyType(value = "list", empty = true)
    @RequestMapping(value = "/rpush", method = RequestMethod.POST)
    public Object rpush(HttpServletRequest request,
                        @RequestParam String key,
                        @RequestParam String values) throws Exception {
        val jedis = tool.getJedis(request);
        //json转list
        String[] list = mapper.readValue(values, String[].class);
        Long lpush = jedis.rpush(key, list);
        Map map = new HashMap();
        map.put("key", key);
        map.put("values", list);
        ResData res = new ResData(map);
        res.setRedis(lpush);
        return new ResJson(200, "成功", res);
    }

    /**
     * 根据index修改xalue
     *
     * @param key      list的key
     * @param index    索引
     * @param value    要修改的值
     * @param oldValue 旧值，用于验证
     * @return {map:{"index":100,"value":100}}
     */
    @VerifyKeyType("list")
    @RequestMapping(value = "/lset", method = RequestMethod.POST)
    public Object lset(HttpServletRequest request,
                       @RequestParam String key,
                       @RequestParam long index,
                       @RequestParam String value,
                       @RequestParam String oldValue) throws Exception {
        val jedis = tool.getJedis(request);
        index--;
        String lindex = jedis.lindex(key, index);
        if (!oldValue.equals(lindex)) {
            return new ResJson(4000, "修改失败", new ResData("数据可能已经被改变，请刷新后重新发起修改操作"));
        }
        String lset = jedis.lset(key, index, value);
        Map map = new HashMap();
        map.put("index", index + 1);
        map.put("value", value);
        map.put("oldValue", oldValue);
        ResData res = new ResData(map);
        res.setRedis(lset);
        return new ResJson(200, "成功", res);
    }

    /**
     * 获取list
     *
     * @param key   list的key
     * @param sizes 一页的数量
     * @param page  第几页
     * @return data数据结构 = {map:{"total":100},list:[{"index":0,"key":"aaa"}]}
     */
    @VerifyKeyType(value = "list",empty = true)
    @RequestMapping(value = "/lrange", method = RequestMethod.POST)
    public Object lrange(HttpServletRequest request,
                         @RequestParam String key,
                         @RequestParam(defaultValue = "20") long sizes,
                         @RequestParam(defaultValue = "1") long page) throws Exception {
        val jedis = tool.getJedis(request);
        Long start = Long.valueOf((page - 1) * sizes);
        Long end = Long.valueOf(page * sizes - 1); //第一也才减1
        List<String> lrange = jedis.lrange(key, start, end);
        List list = new ArrayList();
        for (int i = 0; i < lrange.size(); i++) {
            Map map = new HashMap();
            map.put("value", lrange.get(i));
            map.put("index", start + i + 1);  // index 从0开始，转成1开始
            list.add(map);
        }
        ResData resData = new ResData();
        resData.setList(list);
        Map map = new HashMap();
        map.put("total", jedis.llen(key));
        resData.setMap(map);
        return new ResJson(200, "成功", resData);
    }

    /**
     * 根据key index value 删除
     *
     * @param key   list的key
     * @param index list的index
     * @param value index对应的值，用来验证
     * @return data数据结构 = {map:{"index":index,"value":value}}
     */
    @VerifyKeyType("list")
    @RequestMapping(value = "del", method = RequestMethod.POST)
    public Object del(HttpServletRequest request,
                      @RequestParam String key,
                      @RequestParam long index,
                      @RequestParam String value) throws Exception {
        val jedis = tool.getJedis(request);
        index--;
        String lindex = jedis.lindex(key, index);
        if (!value.equals(lindex)) {
            return new ResJson(4000, "删除失败", new ResData("数据可能已经被改变，请刷新后重新发起删除操作"));
        }
        String temp = "yyz-del-temp-@#$%&*()_!";
        // 先设置指定值，再通过指定值删除
        jedis.lset(key, index, temp);
        jedis.lrem(key, 1, temp);
        Map map = new HashMap();
        map.put("key", key);
        map.put("index", index);
        map.put("value", value);
        ResData resData = new ResData(map);
        return new ResJson(200, "成功", resData);
    }

}
